package com.virtualightning.mvvm.impl.proxy

import android.content.Context
import android.content.Intent
import android.content.res.AssetManager
import android.content.res.Resources
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity

/**
 *  Anchor : Create by CimZzz
 *  Time : 2021/1/27 16:03:07
 *  Project : zxs-new
 *  宿主 Activity
 *  这里采用多 DexClassLoader 的方式实现插件化
 */
class HostActivity: AppCompatActivity() {
    companion object {
        ///////////////////////////////////////////////////////////////////////////
        // Add by CimZzz on 2021/1/27 下午4:46
        // 生成启动宿主 Activity 的 Intent
        ///////////////////////////////////////////////////////////////////////////
        fun getSpawnActivityIntent(context: Context, activityName: String, apkPath: String, dexOutDirPath: String) : Intent {
            val intent = Intent(context, HostActivity::class.java)
            intent.putExtra("ActivityName", activityName)
            intent.putExtra("ApkPath", apkPath)
            intent.putExtra("DexOutDirPath", dexOutDirPath)
            return intent
        }

        fun getSpawnActivityIntent(context: Context, activityName: String, hookManager: HookManager) : Intent {
            val intent = Intent(context, HostActivity::class.java)
            intent.putExtra("ActivityName", activityName)
            intent.putExtra("ApkPath", hookManager.apkPath)
            intent.putExtra("DexOutDirPath", hookManager.dexOutDirPath)
            return intent
        }
    }

    ///////////////////////////////////////////////////////////////////////////
    // Add by CimZzz on 2021/1/27 下午4:49
    // Hook 管理器
    ///////////////////////////////////////////////////////////////////////////
    private var hookManager: HookManager? = null

    ///////////////////////////////////////////////////////////////////////////
    // Add by CimZzz on 2021/1/27 下午4:58
    // 代理接口
    ///////////////////////////////////////////////////////////////////////////
    private var proxyInterface: IProxyInterface? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        val activityName = intent.getStringExtra("ActivityName")
        val apkPath = intent.getStringExtra("ApkPath")
        val dexOutDirPath = intent.getStringExtra("DexOutDirPath")

        if(activityName == null || apkPath == null || dexOutDirPath == null) {
            // 参数非法，直接 Finish
            finish()
            return
        }

        val tempManager = kotlin.runCatching {
            HookManager.initHookManager(this, apkPath, dexOutDirPath)
        }.getOrNull()

        if(tempManager == null) {
            // 生成 HookManager 失败
            finish()
            return
        }

        hookManager = tempManager

        proxyInterface = kotlin.runCatching {
            val proxyInterface = tempManager.classLoader.loadClass(activityName).newInstance() as IProxyInterface
            proxyInterface.attach(this)
            proxyInterface.onRealCreated(savedInstanceState)
            proxyInterface
        }.getOrNull()

        if(proxyInterface == null) {
            // 生成 ProxyInterface 失败
            finish()
            return
        }
    }

    override fun onStart() {
        super.onStart()
        proxyInterface?.onStart()
    }

    override fun onResume() {
        super.onResume()
        proxyInterface?.onResume()
    }

    override fun onPause() {
        super.onPause()
        proxyInterface?.onPause()
    }

    override fun onStop() {
        super.onStop()
        proxyInterface?.onStop()
    }

    override fun onDestroy() {
        super.onDestroy()
        proxyInterface?.onDestroy()
        proxyInterface = null
    }

    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        proxyInterface?.onSaveInstanceState(outState)
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        proxyInterface?.onActivityResult(requestCode, resultCode, data)
    }

    override fun getClassLoader(): ClassLoader {
        return hookManager?.classLoader ?: super.getClassLoader()
    }

    override fun getAssets(): AssetManager {
        return hookManager?.assetManager ?: super.getAssets()
    }

    override fun getResources(): Resources {
        return hookManager?.resources ?: super.getResources()
    }

    override fun onNewIntent(intent: Intent?) {
        super.onNewIntent(intent)
    }

    override fun startActivityForResult(intent: Intent?, requestCode: Int, options: Bundle?) {
        val existIntent = intent ?: return
        val existHookManager = hookManager ?: return
        val componentName = existIntent.component
        if(componentName == null) {
            super.startActivityForResult(intent, requestCode, options)
            return
        }
        super.startActivityForResult(getSpawnActivityIntent(this, componentName.className, existHookManager), requestCode, options)
    }

    override fun startActivity(intent: Intent?) {
        val existIntent = intent ?: return
        val existHookManager = hookManager ?: return
        val componentName = existIntent.component
        if(componentName == null) {
            super.startActivity(intent)
            return
        }
        super.startActivity(getSpawnActivityIntent(this, componentName.className, existHookManager))
    }
}